package cn.edu.scnu.thewonderofink.ui.home

import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import android.app.AlertDialog
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Color
import android.graphics.Matrix
import android.graphics.drawable.ColorDrawable
import android.media.ExifInterface
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.MediaStore
import android.util.Base64
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import cn.edu.scnu.thewonderofink.R
import cn.edu.scnu.thewonderofink.databinding.FragmentHomeBinding
import cn.edu.scnu.thewonderofink.databinding.MyAlertDialogBinding
import java.io.ByteArrayOutputStream
import java.io.File


class HomeFragment : Fragment() {

    val viewModel by lazy { ViewModelProvider(this).get(HomeViewModel::class.java) }
    private var _binding: FragmentHomeBinding? = null

    private val binding get() = _binding!!

    private lateinit var imageUri: Uri
    private lateinit var outputImage: File

    private val sendImageRequestCode = 100
    private val getFromAlbumRequestCode = 2

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {

        _binding = FragmentHomeBinding.inflate(inflater, container, false)
        val root: View = binding.root


        return root
    }

    @SuppressLint("NotifyDataSetChanged")
    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)

        // 以下为bannerView的使用代码
        // 此处要是可以通过网络请求获取文件的话，就可以使用observe进行数据传入
        // 当前写法为静态数据
        val banner = binding.banner
        banner.updateData(listOf(R.drawable.ic_home, R.drawable.ic_dictionary, R.drawable.ic_me))
        banner.autoScroll(true)


        // 对Base64字符串图片进行处理
        viewModel.recognitionLiveData.observe(viewLifecycleOwner) {
            val result = it.getOrNull()
            if (result != null) {
                // 获取识别结果
                val char = result.char
                // 显示识别结果
                val layoutInflater = LayoutInflater.from(context)
                val alertDialogView = layoutInflater.inflate(R.layout.my_alert_dialog, null)
                val myAlertDialogBinding = MyAlertDialogBinding.bind(alertDialogView)
                myAlertDialogBinding.alertDialogContent.text = char
                val dialog = AlertDialog.Builder(context)
                    .setView(alertDialogView)
                    .create()
                dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
                myAlertDialogBinding.alertDialogButton.setOnClickListener {
                    dialog.dismiss()
                }
                dialog.show()
            } else {
                Toast.makeText(context, "识别失败", Toast.LENGTH_SHORT).show()
            }
        }

        //相机按钮点击事件处理
        val imageButton = binding.imageButton
        imageButton.setOnClickListener {
            requestCameraPermission()
        }

        // 从相册选择图片
        val homeButton = binding.homeButton
        homeButton.setOnClickListener {
            requestGalleryPermission()
        }


    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }

    /**
     * @说明 请求相机权限
     */
    private fun requestCameraPermission() {
        if (ContextCompat.checkSelfPermission(this.requireContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            this.requestPermissions(arrayOf(Manifest.permission.CAMERA), sendImageRequestCode)
        } else {
            takePhoto()
        }
    }

    /**
     * @说明 请求相册权限
     */
    private fun requestGalleryPermission() {
        val permission = if (Build.VERSION.SDK_INT >= 33) {
            Manifest.permission.READ_MEDIA_IMAGES
        } else {
            Manifest.permission.READ_EXTERNAL_STORAGE
        }

        if (ContextCompat.checkSelfPermission(this.requireContext(), permission) != PackageManager.PERMISSION_GRANTED) {
            this.requestPermissions(arrayOf(permission), getFromAlbumRequestCode)
        } else {
            selectPhoto()
        }
    }

    /**
     * @说明 请求权限后，进行判断
     */
    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        Log.d("Testing", "Approaching onRequestPermissionsResult")
        when (requestCode) {
            sendImageRequestCode -> {
                Log.d("Testing", "Approaching onRequestPermissionsResult getImage")
                if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    takePhoto()
                } else {
                    // 权限被拒绝
                    Toast.makeText(
                        context,
                        "Camera permission is required to take a photo.",
                        Toast.LENGTH_SHORT
                    ).show()
                }
            }
            getFromAlbumRequestCode -> {
                Log.d("Testing", "Approaching onRequestPermissionsResult getAlbum")
                if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    selectPhoto()
                } else {
                    // 权限被拒绝
                    Toast.makeText(
                        context,
                        "Album permission is required to select a photo.",
                        Toast.LENGTH_SHORT
                    ).show()
                }
            }
        }
    }



    /**
     *  @说明 启动相机并拍照
     */
    private fun takePhoto() {
        // 创建File对象，用于存储拍照后的图片

        outputImage = File(context?.externalCacheDir, "output_image.jpg")
        if (outputImage.exists()) {
            outputImage.delete()
        }
        outputImage.createNewFile()
        imageUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            FileProvider.getUriForFile(
                requireContext(),
                "cn.edu.scnu.thewonderofink.fileprovider",
                outputImage
            )
        } else {
            Uri.fromFile(outputImage)
        }
        // 启动相机程序
        val intent = Intent("android.media.action.IMAGE_CAPTURE")
        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri)
        startActivityForResult(intent, sendImageRequestCode)
    }

    /**
     * @说明 从相册中选择图片
     */
    private fun selectPhoto() {
        val intent = Intent(Intent.ACTION_PICK)
        intent.setType("image/*")
        startActivityForResult(intent, getFromAlbumRequestCode)
    }

    /**
     * @说明 获取图片后的处理
     */
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when (requestCode) {
            sendImageRequestCode -> {
                if (resultCode == Activity.RESULT_OK) {
                    // 将获取到的数据转换为BitMap类型的图片，并进行旋转
                    val bitmap = rotateIfRequired(
                        BitmapFactory.decodeStream(
                            context?.contentResolver?.openInputStream(imageUri)
                        )
                    )
                    // 压缩bitmap图片大小
                    val newBitmap = Bitmap.createScaledBitmap(bitmap, 224, 224, true)
                    // 将BitMap类型的图片转换为字节数组
                    val baos = ByteArrayOutputStream()
                    newBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos)
                    val imageBytes = baos.toByteArray()
                    // 将字节数组转换为Base64字符串
                    val imageBase64 = Base64.encodeToString(imageBytes, Base64.DEFAULT)
                    viewModel.recognitionImage(imageBase64)
                }
            }

            getFromAlbumRequestCode -> {
                if (resultCode == Activity.RESULT_OK && data != null) {
                    // 获取选择的图片
                    val selectedImage = data.data
                    // 如果在Android 14或更高版本，需要获取持久化的Uri权限
                    // if (Build.VERSION.SDK_INT >= 33) {
                    //     selectedImage?.let {
                    //         requireContext().contentResolver.takePersistableUriPermission(
                    //             it,
                    //             Intent.FLAG_GRANT_READ_URI_PERMISSION
                    //         )
                    //     }
                    // }
                    // 将选择的图片转换为BitMap类型的图片，并进行旋转
                    val bitmap = selectedImage?.let { getBitmapFromUri(it) }
                    // 将BitMap类型的图片转换为字节数组
                    val baos = ByteArrayOutputStream()
                    bitmap?.compress(Bitmap.CompressFormat.JPEG, 100, baos)
                    val imageBytes = baos.toByteArray()
                    // 将字节数组转换为Base64字符串
                    val imageBase64 = Base64.encodeToString(imageBytes, Base64.DEFAULT)
                    viewModel.recognitionImage(imageBase64)
                }
            }
        }
    }

    /**
     * @说明 判断图片是否需要旋转，并进行旋转
     */
    private fun rotateIfRequired(bitmap: Bitmap): Bitmap {
        val exif = ExifInterface(outputImage.path)
        val orientation = exif.getAttributeInt(
            ExifInterface.TAG_ORIENTATION,
            ExifInterface.ORIENTATION_NORMAL
        )
        return when (orientation) {
            ExifInterface.ORIENTATION_ROTATE_90 -> rotateBitmap(bitmap, 90)
            ExifInterface.ORIENTATION_ROTATE_180 -> rotateBitmap(bitmap, 180)
            ExifInterface.ORIENTATION_ROTATE_270 -> rotateBitmap(bitmap, 270)
            else -> bitmap
        }
    }

    /**
     * @说明 旋转图片
     */
    private fun rotateBitmap(bitmap: Bitmap, degree: Int): Bitmap {
        val matrix = Matrix()
        matrix.postRotate(degree.toFloat())
        val rotatedBitmap = Bitmap.createBitmap(
            bitmap, 0, 0, bitmap.width, bitmap.height,
            matrix, true
        )
        bitmap.recycle() // 将不再需要的Bitmap对象回收
        return rotatedBitmap
    }

    private fun getBitmapFromUri(uri: Uri) = context?.contentResolver
        ?.openFileDescriptor(uri, "r")?.use {
            BitmapFactory.decodeFileDescriptor(it.fileDescriptor)
        }
}